package com.ctlele.team.space.util;

import android.content.Context;
import android.text.TextUtils;
import android.util.Log;

import com.alibaba.fastjson.JSON;
import com.ctlele.team.space.R;
import com.ctlele.team.space.api.Api;
import com.ctlele.team.space.api.ApiStatusCode;
import com.ctlele.team.space.api.Apis;
import com.ctlele.team.space.entity.vo.FileTypeVo;
import com.ctlele.team.space.entity.vo.resp.FileTypeListResp;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import okhttp3.Call;
import okhttp3.Response;

public class FileTypeUtils {

    private static final String TAG = "FileTypeUtils";

    public static boolean INIT = false;

    private static final Map<String, FileTypeVo> FILE_TYPE_MAP = new HashMap<>();

    private static final Map<String, FileTypeVo> FILE_TYPE_MAP_WITH_ID = new HashMap<>();

    private static final Map<String, String> OFFICE_CONTENT_TYPE = new HashMap<>();

    public static final String FILE_TYPE_IMG = "img";

    public static final String FILE_TYPE_VIDEO = "video";

    public static final String FILE_TYPE_TEXT = "text";

    public static final String FILE_TYPE_OFFICE_WORD = "word";

    public static final String FILE_TYPE_OFFICE_EXCEL = "excel";

    public static final String FILE_TYPE_OFFICE_PPT = "pptx";

    public static final String FILE_TYPE_OTHER = "other";

    private interface FileContentType {
        String IMAGE = "image";

        String VIDEO = "video";

        String TEXT = "text";

        String APPLICATION = "application";
    }

    public static FileTypeVo fromId(String typeId) {
        if (TextUtils.isEmpty(typeId)) {
            throw new IllegalArgumentException("filename not found");
        }

        FileTypeVo vo = FILE_TYPE_MAP_WITH_ID.get(typeId);
        if (vo == null) {
            return FILE_TYPE_MAP.get("other");
        }
        return vo;
    }

    public static FileTypeVo fromContentType(Context context, String filename) {
        if (TextUtils.isEmpty(filename)) {
            throw new IllegalArgumentException("filename not found");
        }

        String fromName = URLConnection.guessContentTypeFromName(filename);

        if (TextUtils.isEmpty(fromName)) {
            Log.w(TAG, "content-type unknown, returned default");
            return get(FILE_TYPE_OTHER);
        }

        String[] pair = fromName.split("/");
        if (pair.length < 2) {
            Log.w(TAG, "content-type parse failed, returned default");
            return get(FILE_TYPE_OTHER);
        }

        switch (pair[0]) {
            case FileContentType.IMAGE:
                return get(FILE_TYPE_IMG);
            case FileContentType.VIDEO:
                return get(FILE_TYPE_VIDEO);
            case FileContentType.TEXT:
                return get(FILE_TYPE_TEXT);
            case FileContentType.APPLICATION:
                return parseApplicationContentType(context, pair[1]);
            default:
                Log.w(TAG, "content-type not support, returned default");
                return get(FILE_TYPE_OTHER);
        }
    }

    private static FileTypeVo parseApplicationContentType(Context context, String applicationType) {
        if (OFFICE_CONTENT_TYPE.isEmpty()) {
            try (InputStream stream = context.getAssets().open("office_content_type")) {
                BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
                String line;
                while (!TextUtils.isEmpty((line = reader.readLine()))) {
                    String[] typeAndContentType = line.split(",");
                    String[] pair = typeAndContentType[1].split("/");
                    OFFICE_CONTENT_TYPE.put(pair[1], typeAndContentType[0]);
                }
            } catch (Exception e) {
                Log.e(TAG, e.getMessage(), e);
            }
        }
        String val = OFFICE_CONTENT_TYPE.getOrDefault(applicationType, "");
        switch (val) {
            // case ".doc":
            case ".docx":
                return get(FILE_TYPE_OFFICE_WORD);
            // case ".xls":
            case ".xlsx":
                return get(FILE_TYPE_OFFICE_EXCEL);
            // case ".ppt":
            case ".pptx":
                return get(FILE_TYPE_OFFICE_PPT);
            default:
                return get(FILE_TYPE_OTHER);
        }
    }

    public static FileTypeVo get(String typeSimpleName) {
        FileTypeVo vo = FILE_TYPE_MAP.get(typeSimpleName);
        if (vo == null) {
            return FILE_TYPE_MAP.get("other");
        }
        return vo;
    }

    public static void init(Context context) {
        Api.get(context, Apis.FILE_TYPE_LIST, new ArrayList<>(), new Api.ApiCallback() {
            @Override
            public void onFailure(Context context, Call call, IOException e) {
                Log.e(TAG, e.getMessage(), e);
            }

            @Override
            public void onResponse(Context context, Call call, Response response) throws IOException {
                String res = response.body().string();
                FileTypeListResp resp = JSON.parseObject(res, FileTypeListResp.class);
                if (resp != null && resp.getCode().equals(ApiStatusCode.OK)) {
                    List<FileTypeVo> list = resp.getData();
                    for (FileTypeVo vo : list) {
                        FILE_TYPE_MAP.put(vo.getTypeSimpleName(), vo);
                        FILE_TYPE_MAP_WITH_ID.put(vo.getTypeId(), vo);
                    }
                }
                INIT = true;
            }
        });
    }
}
